package com.helin.helinhealth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.helin.helinhealth.dto.AdminLoginRequest;
import com.helin.helinhealth.dto.AdminRegisterRequest;
import com.helin.helinhealth.entity.Admin;
import com.helin.helinhealth.mapper.AdminMapper;
import com.helin.helinhealth.service.AdminService;
import com.helin.helinhealth.utils.JwtUtils;
import com.helin.helinhealth.utils.PasswordEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 管理员服务实现类
 * 
 * <p>
 * 该类实现了AdminService接口定义的所有方法，
 * 主要处理后台管理系统的用户认证、用户注册等功能。
 * </p>
 */
@Slf4j
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    /**
     * 密码编码工具
     */
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * JWT工具类
     */
    @Autowired
    private JwtUtils jwtUtils;
    
    /**
     * 管理员登录
     * 
     * @param loginRequest 登录请求DTO
     * @return JWT令牌
     */
    @Override
    @Transactional
    public String login(AdminLoginRequest loginRequest) {
        // 根据用户名查询用户
        Admin admin = getAdminByUsername(loginRequest.getUsername());
        if (admin == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 验证账号状态
        if (admin.getStatus() != null && admin.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(loginRequest.getPassword(), admin.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 更新最后登录时间
        updateLastLoginTime(admin.getId());
        
        // 生成JWT令牌
        String token = generateToken(admin);
        
        log.info("管理员 {} 登录成功", admin.getUsername());
        return token;
    }
    
    /**
     * 管理员注册
     * 
     * @param registerRequest 注册请求DTO
     * @return 用户信息
     */
    @Override
    @Transactional
    public Admin register(AdminRegisterRequest registerRequest) {
        // 验证两次密码是否一致
        if (!Objects.equals(registerRequest.getPassword(), registerRequest.getConfirmPassword())) {
            throw new RuntimeException("两次密码不一致");
        }
        
        // 验证用户名是否已存在
        if (isUsernameExists(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建新管理员对象
        Admin admin = new Admin();
        admin.setUsername(registerRequest.getUsername());
        admin.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        admin.setNickname(registerRequest.getNickname());
        admin.setPhone(registerRequest.getPhone());
        admin.setEmail(registerRequest.getEmail());
        admin.setRole(2); // 默认为普通管理员
        admin.setStatus(1); // 默认启用
        admin.setCreateTime(LocalDateTime.now());
        admin.setUpdateTime(LocalDateTime.now());
        
        // 保存到数据库
        save(admin);
        
        log.info("新管理员注册成功: {}", admin.getUsername());
        
        // 返回新用户信息（注意不要返回密码）
        admin.setPassword(null);
        return admin;
    }
    
    /**
     * 根据用户名获取管理员信息
     * 
     * @param username 用户名
     * @return 管理员信息
     */
    @Override
    public Admin getAdminByUsername(String username) {
        LambdaQueryWrapper<Admin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Admin::getUsername, username);
        queryWrapper.eq(Admin::getIsDeleted, 0); // 未删除的用户
        return getOne(queryWrapper);
    }
    
    /**
     * 检查用户名是否已存在
     * 
     * @param username 用户名
     * @return 是否已存在
     */
    @Override
    public boolean isUsernameExists(String username) {
        return getAdminByUsername(username) != null;
    }
    
    /**
     * 更新管理员最后登录时间
     * 
     * @param id 管理员ID
     */
    @Override
    @Transactional
    public void updateLastLoginTime(Long id) {
        Admin admin = getById(id);
        if (admin != null) {
            admin.setLastLoginTime(LocalDateTime.now());
            updateById(admin);
        }
    }
    
    /**
     * 为管理员生成JWT令牌
     * 
     * <p>
     * 根据管理员信息生成包含特定声明的JWT令牌，
     * 声明中包含用户ID、用户名和角色等信息。
     * </p>
     * 
     * @param admin 管理员信息
     * @return JWT令牌
     */
    private String generateToken(Admin admin) {
        return jwtUtils.generateToken("admin:" + admin.getUsername());
    }
} 